package com.sfy.core.example.service;


import com.sfy.core.example.RpcApplication;
import com.sfy.core.example.model.RpcRequest;
import com.sfy.core.example.model.RpcResponse;
import com.sfy.core.example.registry.LocalRegistry;
import com.sfy.core.example.serializer.Serializer;
import com.sfy.core.example.serializer.SerializerFactory;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;

import java.io.IOException;
import java.lang.reflect.Method;

/**
 * 1、反序列化请求为对象，并从对象中获取参数
 * 2.根据服务名称从本地注册器中获取对象的实现类
 * 3.通过反射机制调用
 * 4.对返回结果进行序列化
 */
public class HttpServerHandler implements Handler<HttpServerRequest> {

    @Override
    public void handle(HttpServerRequest request) {
        //指定序列化器
        final Serializer serializer =
                SerializerFactory.getInstance(RpcApplication.getRpcConfig().getSerializer());

        // 记录日志
        System.out.println("Received request: " + request.method() + " " + request.uri());

        request.bodyHandler(body->{
            byte[] bytes = body.getBytes();
            RpcRequest rpcRequest = null;
            try {
                rpcRequest = serializer.deserialize(bytes,RpcRequest.class);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            // 构造响应对象
            RpcResponse response = new RpcResponse();
            if (rpcRequest == null){
                response.setMessage("request is null");
                doResponse(request,response,serializer);
                return;
            }
            try{
                Class<?> implClass = LocalRegistry.get(rpcRequest.getServiceName());
                Method method = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                Object result = method.invoke(implClass.newInstance(), rpcRequest.getArgs());
                //封装结果
                response.setData(result);
                response.setDataType(method.getReturnType());
                response.setMessage("ok");
            } catch (Exception  e) {
                throw new RuntimeException(e);
            }

            //响应
            doResponse(request,response,serializer);
        });
    }


    /**
     * 响应
     *
     * @param request
     * @param rpcResponse
     * @param serializer
     */
    void doResponse(HttpServerRequest request, RpcResponse rpcResponse, Serializer serializer) {
        HttpServerResponse httpServerResponse = request.response()
                .putHeader("content-type", "application/json");
        try {
            // 序列化
            byte[] serialized = serializer.serialize(rpcResponse);
            httpServerResponse.end(Buffer.buffer(serialized));
        } catch (IOException e) {
            e.printStackTrace();
            httpServerResponse.end(Buffer.buffer());
        }
    }
}
